#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "dialogconfig.h"
#include "dialogrdp.h"
#include <QMessageBox>
#include <QDebug>
#include <QCloseEvent>
#include <QJsonObject>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    //设置窗口大小和图标
    resize(600, 400);
    setWindowFlags(windowFlags()& ~Qt::WindowMaximizeButtonHint);
    setFixedSize(this->width(), this->height());
    setWindowIcon(QIcon(":/res/icon.ico"));

    // 设置客户端列表组件
    ui->clientWidget->setColumnCount(4);                                                    //设置为3列
    ui->clientWidget->setHorizontalHeaderLabels(QStringList() <<"描述符" << "IP地址" <<"主机名称" << "延时");  //设置列名称
    ui->clientWidget->setStyleSheet("QHeaderView::section{background-color:rgb(194,194,194);color:black}\
                                    QTableView:item::selected{background-color:rgb(238,238,238);}");
    ui->clientWidget->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Fixed);     //设置第一列固定宽度
    ui->clientWidget->setColumnWidth(0 , 100);                                              //设置第一列宽度为80
    ui->clientWidget->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch);   //设置第二列自动宽度
    ui->clientWidget->horizontalHeader()->setSectionResizeMode(2, QHeaderView::Stretch);   //设置第三列自动宽度
    ui->clientWidget->horizontalHeader()->setSectionResizeMode(3, QHeaderView::Fixed);     //设置第四列固定宽度
    ui->clientWidget->setColumnWidth(3 , 80);                                              //设置第四列宽度为80
    ui->clientWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);              //设置不可编辑
    ui->clientWidget->setContextMenuPolicy(Qt::CustomContextMenu);                     //开启右键菜单
    ui->clientWidget->setSelectionBehavior(QAbstractItemView::SelectRows);             //设置整行选中
    ui->clientWidget->setFocusPolicy(Qt::NoFocus);                                     //关闭选中虚线框
    ui->clientWidget->verticalHeader()->hide();                                        //隐藏列的表头

    // 设置状态栏
    ui->statusbar->setSizeGripEnabled(false);   //去掉状态栏右下角的三角
    setStatusBarText();

    //设置菜单action组，保证每一项设置是单选的
    QActionGroup* ppiActionGroup = new QActionGroup(this);
    ppiActionGroup->addAction(ui->actionppi1);
    ppiActionGroup->addAction(ui->actionppi2);
    ppiActionGroup->addAction(ui->actionppi3);
    ppiActionGroup->addAction(ui->actionppi4);
    ui->actionppi1->setCheckable(true);
    ui->actionppi2->setCheckable(true);
    ui->actionppi3->setCheckable(true);
    ui->actionppi4->setCheckable(true);
    QActionGroup * bitActionGroup = new QActionGroup(this);
    bitActionGroup->addAction(ui->actionbit1);
    bitActionGroup->addAction(ui->actionbit2);
    bitActionGroup->addAction(ui->actionbit3);
    bitActionGroup->addAction(ui->actionbit4);
    ui->actionbit1->setCheckable(true);
    ui->actionbit2->setCheckable(true);
    ui->actionbit3->setCheckable(true);
    ui->actionbit4->setCheckable(true);
    QActionGroup * fpsActionGroup = new QActionGroup(this);
    fpsActionGroup->addAction(ui->actionfps1);
    fpsActionGroup->addAction(ui->actionfps2);
    fpsActionGroup->addAction(ui->actionfps3);
    fpsActionGroup->addAction(ui->actionfps4);
    ui->actionfps1->setCheckable(true);
    ui->actionfps2->setCheckable(true);
    ui->actionfps3->setCheckable(true);
    ui->actionfps4->setCheckable(true);

    //手动设置菜单组的信号和槽
    connect(ppiActionGroup, &QActionGroup::triggered , this, &MainWindow::on_ppiActionGroup_triggered);
    connect(bitActionGroup, &QActionGroup::triggered , this, &MainWindow::on_bitActionGroup_triggered);
    connect(fpsActionGroup, &QActionGroup::triggered , this, &MainWindow::on_fpsActionGroup_triggered);

    //载入程序配置
    config.getConfigs();
    if(config.scWidth == 800 && config.scHeight == 600){
        ui->actionppi1->setChecked(true);
    }else if(config.scWidth == 1024 && config.scHeight == 768){
        ui->actionppi2->setChecked(true);
    }else if(config.scWidth == 1280 && config.scHeight == 800){
        ui->actionppi3->setChecked(true);
    }else if(config.scWidth == 1440 && config.scHeight == 900){
        ui->actionppi4->setChecked(true);
    }
    if(config.bit == 8){
        ui->actionbit1->setChecked(true);
    }else if(config.bit == 16){
        ui->actionbit2->setChecked(true);
    }else if(config.bit == 24){
        ui->actionbit3->setChecked(true);
    }else if(config.bit == 32){
        ui->actionbit4->setChecked(true);
    }
    if(config.fps == 10){
        ui->actionfps1->setChecked(true);
    }else if(config.fps == 50){
        ui->actionfps2->setChecked(true);
    }else if(config.fps == 100){
        ui->actionfps3->setChecked(true);
    }else if(config.fps == 500){
        ui->actionfps4->setChecked(true);
    }

    //初始化网络，开启监听
    netCore = new NetCore();
    netCore->config(config.serverPort);
    netCore->start();

    //绑定网络错误信号
    connect(netCore, &NetCore::sigError, this, &MainWindow::on_error);
    //绑定客户端变化信号
    connect(netCore, &NetCore::sigClient, this, &MainWindow::on_client);
}

MainWindow::~MainWindow()
{
    // 停止网络通讯服务
    netCore->stop();
    delete netCore;

    delete ui;
}

// ***********************  以下是私有功能函数 *****************************

// 私有功能函数 - 在客户端列表的tablewidget中添加一项
void MainWindow::addListItem(int Descriptor, QString IpAddress, QString HostName, int Delay)
{
    int curRow = ui->clientWidget->rowCount();
    ui->clientWidget->insertRow(curRow);
    ui->clientWidget->setItem(curRow,0,new QTableWidgetItem(QString("%1").arg(Descriptor)));
    ui->clientWidget->setItem(curRow,1,new QTableWidgetItem(IpAddress));
    ui->clientWidget->setItem(curRow,2,new QTableWidgetItem(HostName));
    if(Delay > 0)
    {
        ui->clientWidget->setItem(curRow,3,new QTableWidgetItem(QString("%1ms").arg(Delay)));
    }
    ui->clientWidget->setRowHeight(curRow, 26);
    setStatusBarText();
}

// 私有功能函数 - 修改客户端列表的tablewidget中一项
void MainWindow::updateListItem(int Descriptor, int Delay)
{
    int curRow = ui->clientWidget->rowCount();
    for(int i = 0; i < curRow ; i ++)
    {
        // qDebug() << "要移除的dp" <<Descriptor << QString("%1").arg(Descriptor) << "；当前dp" << ui->clientWidget->item(i, 0)->text();
        if(ui->clientWidget->item(i, 0)->text() == QString("%1").arg(Descriptor))
        {
            ui->clientWidget->setItem(i,2,new QTableWidgetItem(QString("%1ms").arg(Delay)));
            break;
        }
    }
}

// 私有功能函数 - 移除客户端列表的tablewidget中添加一项
void MainWindow::removeListItem(int Descriptor)
{
    int curRow = ui->clientWidget->rowCount();
    for(int i = 0; i < curRow ; i ++)
    {
        if(ui->clientWidget->item(i, 0)->text() == QString("%1").arg(Descriptor))
        {
            //qDebug() << "要移除的dp" <<Descriptor << QString("%1").arg(Descriptor) << "；当前dp" << ui->clientWidget->item(i, 0)->text();
            ui->clientWidget->removeRow(i);
            break;
        }
    }

    setStatusBarText();
}

// 私有功能函数 - 设置状态栏（默认显示当前主机数量）
void MainWindow::setStatusBarText()
{
    int curRow = ui->clientWidget->rowCount();
    QString strStatus = QString("当前主机 [ %1 ] 台").arg(QString::number(curRow));
    ui->statusbar->showMessage(strStatus);
}

// 私有功能函数 - 设置状态栏
void MainWindow::setStatusBarText(QString strStatus, int timeout = 0)
{
    ui->statusbar->showMessage(strStatus, timeout);
}


// ***********************  以下是UI槽函数 *****************************
// 槽函数 - 程序设置
void MainWindow::on_actionConfig_triggered()
{
    DialogConfig dlgConfig(this);
    dlgConfig.exec();
}

// 槽函数 - 分辨率菜单组
void MainWindow::on_ppiActionGroup_triggered(QAction *action)
{
    //qDebug() << action->text();
    config.getConfigs();
    if(action->text() == "800 x 600"){
        config.scWidth = 800;
        config.scHeight = 600;
    }else if(action->text() == "1024 x 768"){
        config.scWidth = 1024;
        config.scHeight = 768;
    }else if(action->text() == "1280 x 800")
    {
        config.scWidth = 1280;
        config.scHeight = 800;
    }else if(action->text() == "1440 x 900")
    {
        config.scWidth = 1440;
        config.scHeight = 900;
    }
    config.setConfigs();
}

// 槽函数 - 灰度菜单组
void MainWindow::on_bitActionGroup_triggered(QAction *action)
{
    //qDebug() << action->text();
    config.getConfigs();
    if(action->text() == "8bit")
    {
        config.bit = 8;
    }else if(action->text() == "16bit")
    {
        config.bit = 16;
    }else if(action->text() == "24bit")
    {
        config.bit = 24;
    }else if(action->text() == "32bit")
    {
        config.bit = 32;
    }
    config.setConfigs();
}

// 槽函数 - 刷新率菜单组
void MainWindow::on_fpsActionGroup_triggered(QAction *action)
{
    //qDebug() << action->text();
    config.getConfigs();
    if(action->text() == "10ms")
    {
        config.fps = 10;
    }else if(action->text() == "50ms")
    {
        config.fps = 50;
    }else if(action->text() == "100ms")
    {
        config.fps = 100;
    }else if(action->text() == "500ms")
    {
        config.fps = 500;
    }
    config.setConfigs();
}

// 槽函数 - 关于软件
void MainWindow::on_actionabout_triggered()
{
    QMessageBox::about(this , "关于软件", "\n版本号：v 1.0.1213\n创建时间:2022/12/13\n\n开发者：yiyefangzhou24\n联系方式：yiyefangzhou24@qq.com\n\n");
}

// 槽函数 - 户端列表的tablewidget双击事件
void MainWindow::on_clientWidget_cellDoubleClicked(int row, int column)
{
    // 唤醒客户端并下发配置
    int descriptor =  ui->clientWidget->item(row , 0)->text().toInt();
    qDebug() << "准备打开客户端" << descriptor;

    MyTcpSocket * myTcpSocket = netCore->findTcpSocket(descriptor);
    if(myTcpSocket)
    {
        // 启动显示对话框
        DialogRDP *dlgRDP = new DialogRDP(this, myTcpSocket, netCore);
        dlgRDP->setWindowTitle("\\\\" + myTcpSocket->getPeerAddr());
        dlgRDP->show();
    }else
    {
        QMessageBox::critical(this, "错误", "未能找到客户端信息");
    }
}


// ***********************  以下是网络核心通讯槽函数 *****************************
void MainWindow::on_error(int code, QString msg)
{
    setStatusBarText(msg);
}

void MainWindow::on_client(int code, MyTcpSocket * myTcpSocket)
{
    if(code == CLI_NEW)
    {
        addListItem(myTcpSocket->getDescriptor(), myTcpSocket->getPeerAddr(), myTcpSocket->getPeerName());

    }else if(code == CLI_UPDATE)
    {
        updateListItem(myTcpSocket->getDescriptor(), myTcpSocket->getDelay());
    }else
    {
        removeListItem(myTcpSocket->getDescriptor());

    }
}
